import os
import time
import subprocess

from PyQt5.QtGui import QIcon, QPixmap, QPainter, QColor, QBrush, QPen
from PyQt5.QtCore import Qt, QSize, QPoint, pyqtSignal, QEvent, QPropertyAnimation, QRect, QTimer, QEasingCurve
from PyQt5.QtGui import QIcon, QCursor, QMouseEvent, QFont
from PyQt5.QtWidgets import (QDialog, QMainWindow, QWidget, QVBoxLayout,
                             QHBoxLayout, QGridLayout, QLabel, QApplication,
                             QDesktopWidget, QGraphicsDropShadowEffect, QMenu,
                             QAction, QSystemTrayIcon, QScrollArea, QFrame)
from qfluentwidgets import (RoundMenu, PushButton, SearchLineEdit,
                            MessageBox, FluentIcon, ToolButton,
                            TransparentToolButton, ScrollArea, IconWidget,
                            CardWidget, setTheme, Theme)

from utils.utils import get_shortcut_target, scan_all_shortcuts, open_shortcut, load_cache, save_cache
import sys
from icon_fallback import create_fallback_icon
from settings_dialog import SettingsDialog
from config_manager import config  # 导入配置管理器

# 获取所有可用的 FluentIcon 图标


def get_available_icons():
    """获取所有可用的 FluentIcon 图标"""
    icon_names = [name for name in dir(FluentIcon)
                  if not name.startswith('_') and name.isupper()]
    return icon_names


# 打印可用图标以便调试
try:
    print("可用的 FluentIcon 图标:", get_available_icons())
except:
    pass

# 自定义标题栏组件，替换不可用的TitleBar


class CustomTitleBar(QWidget):
    """自定义标题栏"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.parent = parent
        self.setFixedHeight(40)
        self.moving = False
        self.lastPos = None

        # 创建主布局
        self.hBoxLayout = QHBoxLayout(self)
        self.hBoxLayout.setContentsMargins(10, 0, 10, 0)
        self.hBoxLayout.setSpacing(10)

        # 窗口图标
        self.iconLabel = QLabel(self)
        self.iconLabel.setFixedSize(20, 20)

        # 窗口标题
        self.titleLabel = QLabel(self)
        self.titleLabel.setStyleSheet(
            "color: white; font-size: 12px; font-weight: bold;")

        # 窗口按钮
        self.minButton = TransparentToolButton(FluentIcon.MINIMIZE, self)
        self.closeButton = TransparentToolButton(FluentIcon.CLOSE, self)

        # 添加组件到布局
        self.hBoxLayout.addWidget(self.iconLabel)
        self.hBoxLayout.addWidget(self.titleLabel)
        self.hBoxLayout.addStretch(1)

        # 连接信号
        self.minButton.clicked.connect(self.parent.showMinimized)
        self.closeButton.clicked.connect(self.parent.close)

        # 设置样式
        self.setStyleSheet("""
            CustomTitleBar {
                background-color: #0078d4;
                border-top-left-radius: 10px;
                border-top-right-radius: 10px;
            }
            TransparentToolButton {
                color: white;
                background-color: transparent;
            }
            TransparentToolButton:hover {
                background-color: rgba(255, 255, 255, 0.1);
            }
            TransparentToolButton:pressed {
                background-color: rgba(255, 255, 255, 0.2);
            }
        """)

    def setWindowTitle(self, title):
        """设置窗口标题"""
        self.titleLabel.setText(title)

    def setWindowIcon(self, icon):
        """设置窗口图标"""
        try:
            if isinstance(icon, FluentIcon):
                pixmap = icon.icon.pixmap(20, 20)
                self.iconLabel.setPixmap(pixmap)
            elif isinstance(icon, QIcon):
                pixmap = icon.pixmap(20, 20)
                self.iconLabel.setPixmap(pixmap)
        except Exception as e:
            print(f"设置窗口图标时出错: {e}")

    def addWidget(self, widget):
        """添加小部件到标题栏"""
        self.hBoxLayout.insertWidget(self.hBoxLayout.count()-1, widget)

    def mousePressEvent(self, event):
        """鼠标按下事件"""
        if event.button() == Qt.LeftButton:
            self.moving = True
            self.lastPos = event.globalPos()

    def mouseMoveEvent(self, event):
        """鼠标移动事件"""
        if event.buttons() == Qt.LeftButton and self.moving:
            delta = event.globalPos() - self.lastPos
            self.parent.move(self.parent.x() + delta.x(),
                             self.parent.y() + delta.y())
            self.lastPos = event.globalPos()

    def mouseReleaseEvent(self, event):
        """鼠标释放事件"""
        if event.button() == Qt.LeftButton:
            self.moving = False


class FloatingButton(QWidget):
    """悬浮按钮组件"""
    clicked = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedSize(60, 60)
        self.setAttribute(Qt.WA_TranslucentBackground)
        # 设置窗口标志，确保窗口总是在最前面且无边框
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool |
                            Qt.WindowStaysOnTopHint | Qt.WindowDoesNotAcceptFocus)

        # 主布局
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        # 中心内容 - 使用完全圆形设计
        self.btnWidget = CardWidget(self)
        self.btnWidget.setBorderRadius(30)  # 圆形半径为窗口大小的一半
        btnLayout = QVBoxLayout(self.btnWidget)
        btnLayout.setAlignment(Qt.AlignCenter)
        btnLayout.setContentsMargins(0, 0, 0, 0)  # 去掉内部边距

        # 闪电图标
        self.iconLabel = QLabel()
        self.iconLabel.setText("⚡")
        self.iconLabel.setStyleSheet("""
            QLabel {
                font-size: 24px;
                color: white;
                background: transparent;
            }
        """)
        btnLayout.addWidget(self.iconLabel, 0, Qt.AlignCenter)

        # 添加阴影，增强立体感
        shadow = QGraphicsDropShadowEffect(self)
        shadow.setBlurRadius(16)
        shadow.setColor(QColor(0, 0, 0, 180))
        shadow.setOffset(2, 2)
        self.btnWidget.setGraphicsEffect(shadow)

        # 设置样式 - 完美圆形，确保没有边框和背景
        self.btnWidget.setObjectName("floatingBtn")  # 使用对象名便于样式表定位
        self.btnWidget.setStyleSheet("""
            #floatingBtn {
                background-color: #0078d4;
                border: none;
                border-radius: 30px;
            }
        """)

        layout.addWidget(self.btnWidget)

        # 鼠标事件相关变量
        self.pressed = False
        self.pressedPos = QPoint(0, 0)
        self.moving = False

        # 显示状态控制
        self.isNearEdge = False  # 是否靠近边缘
        self.normalWidth = 60    # 正常宽度
        self.edgeWidth = 20      # 边缘宽度
        self.screen = QDesktopWidget().screenGeometry()

        # 边缘检测相关
        self.edgeMargin = 10  # 距离边缘多少像素时触发收缩
        self.edgeAnimationDuration = 200  # 动画持续时间(毫秒)
        self.edgeAnims = {}  # 保存动画对象

        # 右键菜单
        self.menu = RoundMenu(parent=self)
        self.refreshAction = QAction("刷新", self.menu)
        self.settingsAction = QAction("设置", self.menu)
        self.exitAction = QAction("退出", self.menu)

        self.menu.addAction(self.refreshAction)
        self.menu.addAction(self.settingsAction)
        self.menu.addSeparator()
        self.menu.addAction(self.exitAction)

    def mousePressEvent(self, event):
        """鼠标按下事件"""
        if event.button() == Qt.LeftButton:
            self.pressed = True
            self.pressedPos = event.pos()
            self.moving = False
            # 修改为使用对象名，而非直接设置样式，避免覆盖其他属性
            self.btnWidget.setStyleSheet("""
                #floatingBtn {
                    background-color: #005a9e;
                    border: none;
                    border-radius: 30px;
                }
            """)
        elif event.button() == Qt.RightButton:
            self.menu.exec_(QCursor.pos())

    def mouseReleaseEvent(self, event):
        """鼠标释放事件"""
        if event.button() == Qt.LeftButton and self.pressed:
            self.pressed = False
            # 恢复原始样式
            self._updateStyle()
            if not self.moving:
                self.clicked.emit()

    def mouseMoveEvent(self, event):
        """鼠标移动事件"""
        if self.pressed:
            self.moving = True
            # 获取新位置
            newPos = self.mapToParent(event.pos() - self.pressedPos)

            # 获取屏幕尺寸
            screen = QDesktopWidget().screenGeometry()

            # 确保新位置不会超出屏幕边界
            newX = max(0, min(newPos.x(), screen.width() - self.width()))
            newY = max(0, min(newPos.y(), screen.height() - self.height()))

            # 移动到新位置
            self.move(newX, newY)

            # 检查是否靠近边缘
            self._checkEdgeProximity()

    def enterEvent(self, event):
        """鼠标进入事件"""
        # 如果靠近边缘，展开
        if self.isNearEdge:
            self._animateToWidth(self.normalWidth)

        # 设置悬停样式
        self.btnWidget.setStyleSheet("""
            #floatingBtn {
                background-color: #106ebe;
                border: none;
                border-radius: 30px;
            }
        """)

    def leaveEvent(self, event):
        """鼠标离开事件"""
        # 如果靠近边缘，收缩回去
        if self.isNearEdge:
            self._animateToWidth(self.edgeWidth)

        # 恢复原始样式
        self._updateStyle()

    def _checkEdgeProximity(self):
        """检查是否靠近屏幕边缘并相应调整"""
        x = self.x()
        screen_width = self.screen.width()

        # 右边缘检测
        if x + self.width() >= screen_width - self.edgeMargin:
            if not self.isNearEdge:
                self.isNearEdge = True
                self._animateToWidth(self.edgeWidth)
        # 左边缘检测
        elif x <= self.edgeMargin:
            if not self.isNearEdge:
                self.isNearEdge = True
                self._animateToWidth(self.edgeWidth)
        else:
            if self.isNearEdge:
                self.isNearEdge = False
                self._animateToWidth(self.normalWidth)

    def _animateToWidth(self, target_width):
        """使用动画效果改变窗口宽度"""
        if "width" in self.edgeAnims:
            self.edgeAnims["width"].stop()

        # 创建动画对象
        anim = QPropertyAnimation(self, b"geometry")
        anim.setDuration(self.edgeAnimationDuration)
        anim.setStartValue(self.geometry())

        # 将高度保持不变，仅改变宽度
        x = self.x()
        y = self.y()
        height = self.height()

        # 判断是左侧还是右侧贴边，以确保贴边方向正确
        screen_width = self.screen.width()
        if x + self.width() >= screen_width - self.edgeMargin:  # 右侧贴边
            x = screen_width - target_width  # 保持右侧对齐
        elif x <= self.edgeMargin:  # 左侧贴边
            x = 0  # 保持左侧对齐

        anim.setEndValue(QRect(x, y, target_width, height))
        anim.start()

        # 保存动画对象，防止被垃圾回收
        self.edgeAnims["width"] = anim

    def _updateStyle(self):
        """根据当前状态更新样式"""
        self.btnWidget.setStyleSheet(f"""
            #floatingBtn {{
                background-color: #0078d4;
                border: none;
                border-radius: {min(self.width(), self.height()) // 2}px;
            }}
        """)

    def resizeEvent(self, event):
        """大小改变时更新圆角半径"""
        super().resizeEvent(event)
        # 更新圆角半径以保持完美圆形
        radius = min(self.width(), self.height()) // 2
        self.btnWidget.setBorderRadius(radius)
        self._updateStyle()


class ShortcutCard(CardWidget):
    """快捷方式卡片"""

    def __init__(self, shortcut_path, parent=None):
        super().__init__(parent)
        self.shortcut_path = shortcut_path

        # 获取基本信息
        self.shortcut_name = os.path.splitext(
            os.path.basename(shortcut_path))[0]
        self.target_path = get_shortcut_target(shortcut_path) or shortcut_path

        # 设置尺寸策略
        self.setFixedSize(120, 100)

        # 创建布局
        layout = QVBoxLayout(self)
        layout.setAlignment(Qt.AlignCenter)
        layout.setContentsMargins(5, 5, 5, 5)

        # 创建图标
        icon_widget = QWidget()
        icon_layout = QHBoxLayout(icon_widget)
        icon_layout.setContentsMargins(0, 0, 0, 0)
        icon_layout.setAlignment(Qt.AlignCenter)

        self.icon_label = QLabel()
        self.icon_label.setFixedSize(48, 48)
        self.icon_label.setAlignment(Qt.AlignCenter)

        # 提取并设置图标 - 修复null pixmap问题
        try:
            icon_pixmap = extract_icon_pyqt(self.target_path)

            # 检查pixmap是否有效
            if icon_pixmap and not icon_pixmap.isNull() and icon_pixmap.width() > 0:
                self.icon_label.setPixmap(icon_pixmap.scaled(
                    48, 48, Qt.KeepAspectRatio, Qt.SmoothTransformation))
            else:
                # 使用文本替代无效pixmap
                self.icon_label.setText("📄")
                self.icon_label.setStyleSheet("font-size: 24px; color: #555;")
        except Exception as e:
            print(f"设置图标时出错: {e}")
            self.icon_label.setText("📄")
            self.icon_label.setStyleSheet("font-size: 24px; color: #555;")

        icon_layout.addWidget(self.icon_label)

        # 创建标签
        name_label = QLabel(self.shortcut_name)
        name_label.setAlignment(Qt.AlignCenter)
        name_label.setWordWrap(True)
        name_label.setStyleSheet("color: #333333; font-size: 10px;")
        name_label.setFixedHeight(30)  # 限制高度避免文本溢出

        # 添加到布局
        layout.addWidget(icon_widget)
        layout.addWidget(name_label)

        # 设置鼠标指针和工具提示
        self.setCursor(Qt.PointingHandCursor)
        self.setToolTip(self.shortcut_name)

    def mousePressEvent(self, event):
        """鼠标点击事件"""
        if event.button() == Qt.LeftButton:
            open_shortcut(self.shortcut_path)
        elif event.button() == Qt.RightButton:
            self._showContextMenu(event.pos())
        super().mousePressEvent(event)

    def _showContextMenu(self, pos):
        """显示右键菜单"""
        menu = RoundMenu(parent=self)

        runAction = QAction("运行", self)
        runAction.triggered.connect(lambda: open_shortcut(self.shortcut_path))

        locationAction = QAction("打开文件位置", self)
        locationAction.triggered.connect(
            lambda: subprocess.Popen(
                f'explorer /select,"{self.shortcut_path}"', shell=True)
        )

        menu.addAction(runAction)
        menu.addSeparator()
        menu.addAction(locationAction)

        menu.exec_(self.mapToGlobal(pos))


class ShortcutsPanel(QMainWindow):
    """快捷方式面板"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUI()

        # 快捷方式列表
        self.shortcuts = []
        self.displayedShortcuts = []

        # 加载快捷方式
        cached_shortcuts = load_cache()
        if (cached_shortcuts):
            self.shortcuts = cached_shortcuts
        else:
            self.shortcuts = scan_all_shortcuts()
            save_cache(self.shortcuts)

        # 过滤非可执行文件（如果设置为不显示）
        self.filterNonExecutables()

        # 过滤包含关键词的快捷方式
        self.filterKeywords()

        # 显示快捷方式
        self.displayShortcuts()

    def setupUI(self):
        """设置UI"""
        # 窗口设置
        self.setWindowTitle("应用启动器")
        self.resize(700, 500)
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)

        # 修改透明度设置，改为不透明
        self.setAttribute(Qt.WA_TranslucentBackground, False)

        # 主部件
        self.centralWidget = QWidget(self)
        self.centralWidget.setObjectName("centralWidget")
        self.setCentralWidget(self.centralWidget)

        # 主布局
        mainLayout = QVBoxLayout(self.centralWidget)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.setSpacing(0)

        # 使用自定义标题栏
        self.titleBar = CustomTitleBar(self)

        # 使用可用的图标 - 修改为APP图标避免使用未定义的EXPERIMENT
        try:
            # 尝试使用APP图标，如果不可用，则尝试其他
            if hasattr(FluentIcon, 'APP'):
                self.titleBar.setWindowIcon(FluentIcon.APP)
            elif hasattr(FluentIcon, 'DESKTOP'):
                self.titleBar.setWindowIcon(FluentIcon.DESKTOP)
            else:
                icon_path = os.path.join(os.path.dirname(
                    os.path.abspath(__file__)), "assets/app.ico")
                app_icon = QIcon(icon_path)
                self.titleBar.setWindowIcon(app_icon)
        except Exception as e:
            print(f"设置标题栏图标时出错: {e}")

        self.titleBar.setWindowTitle("应用启动器")

        # 添加搜索框到标题栏
        self.searchBox = SearchLineEdit(self)
        self.searchBox.setPlaceholderText("搜索应用")
        self.searchBox.setFixedWidth(200)
        self.searchBox.textChanged.connect(self.filterShortcuts)
        # 将搜索框放在最左侧
        self.titleBar.hBoxLayout.insertWidget(
            1, self.searchBox, 0, Qt.AlignLeft)

        # 重新排列按钮顺序，将操作按钮放在最右侧
        self.titleBar.hBoxLayout.addStretch(1)  # 增加弹性空间

        # 添加刷新按钮
        try:
            refresh_icon = FluentIcon.SYNC if hasattr(
                FluentIcon, 'SYNC') else FluentIcon.REFRESH
            self.refreshButton = TransparentToolButton(refresh_icon, self)
        except:
            # 如果找不到合适的图标，使用没有图标的按钮
            self.refreshButton = TransparentToolButton(self)
            self.refreshButton.setText("🔄")

        self.refreshButton.setToolTip("刷新")
        self.refreshButton.clicked.connect(self.refreshShortcuts)

        # 添加设置按钮
        try:
            settings_icon = FluentIcon.SETTING if hasattr(
                FluentIcon, 'SETTING') else FluentIcon.HELP
            self.settingsButton = TransparentToolButton(settings_icon, self)
        except:
            self.settingsButton = TransparentToolButton(self)
            self.settingsButton.setText("⚙️")

        self.settingsButton.setToolTip("设置")
        self.settingsButton.clicked.connect(self.openSettings)

        # 添加按钮到右侧
        self.titleBar.hBoxLayout.addWidget(self.refreshButton)
        self.titleBar.hBoxLayout.addWidget(self.settingsButton)  # 新增设置按钮
        self.titleBar.hBoxLayout.addWidget(self.titleBar.minButton)
        self.titleBar.hBoxLayout.addWidget(self.titleBar.closeButton)

        # 滚动区域
        self.scrollArea = ScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setViewportMargins(10, 10, 10, 10)

        # 滚动内容
        self.scrollContent = QWidget()

        # 网格布局
        self.gridLayout = QGridLayout(self.scrollContent)
        self.gridLayout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.gridLayout.setContentsMargins(10, 10, 10, 10)
        self.gridLayout.setSpacing(10)

        self.scrollArea.setWidget(self.scrollContent)

        # 主布局添加组件
        mainLayout.addWidget(self.titleBar)
        mainLayout.addWidget(self.scrollArea)

        # 设置样式 - 设置固定不透明背景
        self.setStyleSheet("""
            QMainWindow {
                background-color: rgba(255, 255, 255, 0.95);
                border-radius: 10px;
            }
        """)

        # 中心显示
        self.centerOnScreen()

    def centerOnScreen(self):
        """将窗口居中显示"""
        screenGeometry = QDesktopWidget().availableGeometry()
        x = (screenGeometry.width() - self.width()) // 2
        y = (screenGeometry.height() - self.height()) // 2
        self.move(x, y)

    def displayShortcuts(self):
        """显示快捷方式"""
        # 清空现有项目
        self._clearGridLayout()

        # 显示快捷方式
        col_count = 5
        for idx, path in enumerate(self.displayedShortcuts if self.displayedShortcuts else self.shortcuts):
            try:
                row, col = divmod(idx, col_count)
                shortcut_card = ShortcutCard(path)
                self.gridLayout.addWidget(shortcut_card, row, col)
            except Exception as e:
                print(f"显示快捷方式时出错: {e}")

    def _clearGridLayout(self):
        """清空网格布局"""
        while self.gridLayout.count():
            item = self.gridLayout.takeAt(0)
            widget = item.widget()
            if widget:
                widget.deleteLater()

    def filterShortcuts(self, text):
        """根据文本过滤快捷方式"""
        if not text.strip():
            self.displayedShortcuts = []
        else:
            filter_text = text.lower()
            self.displayedShortcuts = [
                path for path in self.shortcuts
                if filter_text in os.path.splitext(os.path.basename(path))[0].lower()
            ]

        self.displayShortcuts()

    def filterNonExecutables(self):
        """根据设置过滤非可执行文件"""
        if not config.show_non_executables:
            print("过滤非可执行文件")
            filtered_shortcuts = []
            for path in self.shortcuts:
                target_path = get_shortcut_target(path)
                if target_path and self.isExecutable(target_path):
                    filtered_shortcuts.append(path)
            self.shortcuts = filtered_shortcuts
        else:
            print("显示所有文件类型")

    def filterKeywords(self):
        """过滤包含关键词的快捷方式"""
        filter_keywords = config.filter_keywords
        if filter_keywords:
            print(f"过滤包含关键词的快捷方式: {filter_keywords}")
            filtered_shortcuts = []
            for path in self.shortcuts:
                shortcut_name = os.path.splitext(
                    os.path.basename(path))[0].lower()
                # 如果快捷方式名称中不包含任何关键词，则保留
                if not any(keyword.lower() in shortcut_name for keyword in filter_keywords):
                    filtered_shortcuts.append(path)

            print(
                f"过滤前: {len(self.shortcuts)}个快捷方式，过滤后: {len(filtered_shortcuts)}个快捷方式")
            self.shortcuts = filtered_shortcuts
        else:
            print("没有设置过滤关键词")

    def refreshShortcuts(self):
        """刷新快捷方式"""
        self.shortcuts = scan_all_shortcuts()
        # 过滤非可执行文件（如果设置为不显示）
        self.filterNonExecutables()
        # 过滤包含关键词的快捷方式
        self.filterKeywords()
        save_cache(self.shortcuts)
        self.displayShortcuts()

    def openSettings(self):
        """打开设置对话框"""
        try:
            settings_dialog = SettingsDialog(self)
            result = settings_dialog.exec_()

            if result == QDialog.Accepted:
                # 如果用户点击了保存按钮，刷新应用
                self.refreshShortcuts()
        except Exception as e:
            print(f"打开设置对话框时出错: {e}")
            import traceback
            traceback.print_exc()
            from utils.messagebox_helper import show_message_box
            show_message_box("错误", f"打开设置对话框时出错: {e}", self)

    def isExecutable(self, file_path):
        """检查文件是否为可执行文件"""
        executable_extensions = ['.exe', '.bat',
                                 '.cmd', '.com', '.msc', '.ps1', '.msi']
        _, ext = os.path.splitext(file_path.lower())
        return ext in executable_extensions

    def refreshShortcuts(self):
        """刷新快捷方式"""
        self.shortcuts = scan_all_shortcuts()
        # 过滤非可执行文件（如果设置为不显示）
        self.filterNonExecutables()
        save_cache(self.shortcuts)
        self.displayShortcuts()

    def showEvent(self, event):
        """显示事件"""
        super().showEvent(event)
        self.titleBar.raise_()

    def fadeInAnimation(self):
        """改进的淡入动画效果 - 修复面板不显示问题"""
        # 先确保面板已显示且可见，不使用动画
        self.setWindowOpacity(1.0)  # 直接设置为完全不透明
        self.show()
        self.setVisible(True)
        self.raise_()
        self.activateWindow()

        # 注释掉动画代码，直接显示面板
        # 当确认面板显示正常后再添加动画效果
        """
        # 使用更平滑的动画
        anim = QPropertyAnimation(self, b"windowOpacity")
        anim.setDuration(250)
        anim.setStartValue(0.0)
        anim.setEndValue(1.0)
        anim.setEasingCurve(QEasingCurve.OutCubic)
        anim.start()
        """


class AppLauncherFluent(QMainWindow):
    """使用Fluent设计风格的应用启动器"""

    def __init__(self):
        super().__init__()
        try:
            # 隐藏主窗口，防止出现额外窗口
            self.setWindowFlags(Qt.FramelessWindowHint)
            self.hide()

            # 设置主题
            setTheme(Theme.AUTO)

            # 初始化UI
            self.setupUI()

            # 初始化面板 - 确保这块不会出错
            try:
                self.shortcutsPanel = ShortcutsPanel()
            except Exception as e:
                print(f"初始化面板时出错: {e}")
                import traceback
                traceback.print_exc()
                # 创建一个空白面板作为后备
                self.shortcutsPanel = QMainWindow()
                self.shortcutsPanel.setWindowTitle("应用启动器")
                self.shortcutsPanel.resize(700, 500)

            # 连接信号
            self.floatingButton.clicked.connect(self.toggleShortcutsPanel)

            # 系统托盘
            self.setupTrayIcon()
        except Exception as e:
            print(f"初始化应用启动器时出错: {e}")
            import traceback
            traceback.print_exc()

    def setupUI(self):
        """设置UI"""
        try:
            # 获取屏幕信息
            screen = QDesktopWidget().screenGeometry()
            x = screen.width() - 80
            y = screen.height() // 2 - 30

            # 初始化悬浮按钮 - 始终在最前方显示
            self.floatingButton = FloatingButton()
            self.floatingButton.move(x, y)
            self.floatingButton.setWindowFlag(Qt.WindowStaysOnTopHint, True)

            # 注册菜单动作 - 修复索引访问的问题
            try:
                self.floatingButton.refreshAction.triggered.connect(
                    self.refreshShortcuts)
                self.floatingButton.settingsAction.triggered.connect(
                    self.showSettings)
                self.floatingButton.exitAction.triggered.connect(self.exitApp)
            except Exception as e:
                print(f"设置菜单动作时出错: {e}")

            # 在创建悬浮按钮后调整其样式和大小
            self.floatingButton.setGraphicsEffect(None)  # 移除阴影效果

            # 获取当前大小
            current_width = self.floatingButton.width()
            current_height = self.floatingButton.height()
            # 计算新大小 (缩小到85%)
            new_width = int(current_width * 0.85)
            new_height = int(current_height * 0.85)
            self.floatingButton.setFixedSize(new_width, new_height)

        except Exception as e:
            print(f"设置UI时出错: {e}")

    def toggleShortcutsPanel(self):
        """切换快捷方式面板的显示状态 - 修复面板不显示问题"""
        print(
            f"toggleShortcutsPanel 被调用，当前状态: {'可见' if hasattr(self, 'shortcutsPanel') and self.shortcutsPanel and self.shortcutsPanel.isVisible() else '隐藏'}")

        # 确保面板对象存在
        if not hasattr(self, 'shortcutsPanel') or self.shortcutsPanel is None:
            try:
                print("创建新面板")
                self.shortcutsPanel = ShortcutsPanel()
            except Exception as e:
                print(f"创建面板时出错: {e}")
                import traceback
                traceback.print_exc()
                return

        # 处理可见性逻辑
        if self.shortcutsPanel.isVisible():
            # 面板已可见，隐藏它
            print("面板可见，正在隐藏")
            self.shortcutsPanel.hide()
            return

        # 面板不可见，显示它并定位
        print("面板不可见，正在显示")

        # 计算面板显示位置 - 在悬浮按钮旁边
        float_btn_pos = self.floatingButton.pos()
        screen_width = QDesktopWidget().screenGeometry().width()
        screen_height = QDesktopWidget().screenGeometry().height()

        # 计算面板左上角位置，避免超出屏幕
        panel_x = min(float_btn_pos.x() + self.floatingButton.width() + 10,
                      screen_width - self.shortcutsPanel.width())
        panel_y = max(float_btn_pos.y() - self.shortcutsPanel.height() // 2, 0)

        # 如果面板会超出屏幕底部，则调整Y坐标
        if panel_y + self.shortcutsPanel.height() > screen_height:
            panel_y = max(screen_height - self.shortcutsPanel.height(), 0)

        # 如果是靠近屏幕左边，将面板放在悬浮按钮左侧
        if float_btn_pos.x() < screen_width // 2:
            panel_x = max(float_btn_pos.x() -
                          self.shortcutsPanel.width() - 10, 0)

        print(f"移动面板到位置: ({panel_x}, {panel_y})")
        self.shortcutsPanel.move(panel_x, panel_y)

        # 显示面板 - 简化显示逻辑，确保面板可见
        self.shortcutsPanel.show()
        self.shortcutsPanel.raise_()
        self.shortcutsPanel.activateWindow()

        # 强制刷新窗口
        QApplication.processEvents()

    def refreshShortcuts(self):
        """刷新快捷方式"""
        if hasattr(self, 'shortcutsPanel'):
            self.shortcutsPanel.refreshShortcuts()

    def showSettings(self):
        """显示设置"""
        try:
            # 使用新的设置对话框
            settings_dialog = SettingsDialog(self)
            result = settings_dialog.exec_()

            if result == QDialog.Accepted:
                # 如果用户点击了保存按钮，刷新应用
                self.refreshShortcuts()
        except Exception as e:
            print(f"打开设置对话框时出错: {e}")
            import traceback
            traceback.print_exc()
            # 错误时使用辅助函数显示消息框
            from utils.messagebox_helper import show_message_box
            show_message_box("错误", f"打开设置对话框时出错: {e}", self)

    def exitApp(self):
        """退出应用"""
        try:
            # 使用辅助函数显示确认对话框
            from utils.messagebox_helper import show_message_box
            result = show_message_box("退出确认", "确定要退出应用程序吗？", self, yes_no=True)

            # 根据返回值决定是否退出
            if result:  # 用户点击"是"
                QApplication.quit()
        except Exception as e:
            print(f"显示退出确认对话框时出错: {e}")
            # 出错时使用PyQt原生对话框作为后备方案
            from PyQt5.QtWidgets import QMessageBox
            reply = QMessageBox.question(
                self,
                "退出确认",
                "确定要退出应用程序吗？",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )
            if reply == QMessageBox.Yes:
                QApplication.quit()

    def setupTrayIcon(self):
        """设置系统托盘图标"""
        try:
            # 检查图标文件是否存在，如果不存在则创建
            icon_path = os.path.join(os.path.dirname(
                os.path.abspath(__file__)), "assets/app.ico")
            icon = QIcon(icon_path)

            # 创建系统托盘图标
            self.trayIcon = QSystemTrayIcon(self)
            self.trayIcon.setIcon(icon)
            self.trayIcon.setToolTip("应用启动器")

            # 托盘菜单
            trayMenu = QMenu()
            showAction = trayMenu.addAction("显示面板")
            showAction.triggered.connect(self.toggleShortcutsPanel)

            refreshAction = trayMenu.addAction("刷新")
            refreshAction.triggered.connect(self.refreshShortcuts)

            # 添加自启动选项
            autoStartAction = trayMenu.addAction("开机自启动")
            autoStartAction.setCheckable(True)
            autoStartAction.setChecked(self.isAutoStartEnabled())
            autoStartAction.triggered.connect(self.toggleAutoStart)

            trayMenu.addSeparator()

            exitAction = trayMenu.addAction("退出")
            exitAction.triggered.connect(self.exitApp)

            self.trayIcon.setContextMenu(trayMenu)
            self.trayIcon.show()
        except Exception as e:
            print(f"设置系统托盘图标时出错: {e}")

    def toggleAutoStart(self, enabled):
        """切换开机自启动状态"""
        try:
            import winreg as reg

            app_path = os.path.abspath(sys.argv[0])
            # 如果是.py文件，需要使用python解释器启动
            if app_path.endswith('.py'):
                app_path = f'"{sys.executable}" "{app_path}"'
            # 如果是.exe文件，直接使用路径
            elif app_path.endswith('.exe'):
                app_path = f'"{app_path}"'

            autorun_key = reg.OpenKey(
                reg.HKEY_CURRENT_USER,
                r"Software\Microsoft\Windows\CurrentVersion\Run",
                0, reg.KEY_SET_VALUE
            )

            if enabled:
                reg.SetValueEx(autorun_key, "FuckDesktop",
                               0, reg.REG_SZ, app_path)
                print("已设置开机自启动")
            else:
                try:
                    reg.DeleteValue(autorun_key, "FuckDesktop")
                    print("已禁用开机自启动")
                except Exception:
                    # 键可能不存在
                    pass

            reg.CloseKey(autorun_key)
        except Exception as e:
            print(f"设置开机自启动出错: {e}")
            import traceback
            traceback.print_exc()
            from utils.messagebox_helper import show_message_box
            show_message_box("错误", f"设置开机自启动失败: {e}", self)

    def isAutoStartEnabled(self):
        """检查是否已启用开机自启动"""
        try:
            import winreg as reg

            autorun_key = reg.OpenKey(
                reg.HKEY_CURRENT_USER,
                r"Software\Microsoft\Windows\CurrentVersion\Run",
                0, reg.KEY_READ
            )

            try:
                reg.QueryValueEx(autorun_key, "FuckDesktop")
                reg.CloseKey(autorun_key)
                return True
            except Exception:
                reg.CloseKey(autorun_key)
                return False
        except Exception as e:
            print(f"检查开机自启动设置出错: {e}")
            return False

    def show(self):
        """显示应用 - 只显示浮动按钮，不显示主窗口"""
        self.floatingButton.show()
        # 不调用super().show()，避免显示主窗口

# 使用QFileIconProvider提取图标，避免PIL.ImageQt


def extract_icon_pyqt(file_path):
    """使用PyQt提取文件图标"""
    try:
        from PyQt5.QtWidgets import QFileIconProvider
        from PyQt5.QtCore import QFileInfo
        from PyQt5.QtGui import QIcon, QPixmap, QColor, QPainter
        from PyQt5.QtCore import Qt, QSize

        # 创建默认图标
        default_pixmap = QPixmap(32, 32)
        default_pixmap.fill(Qt.transparent)

        # 绘制默认图标
        painter = QPainter(default_pixmap)
        painter.setPen(QColor("#555555"))
        painter.setBrush(QColor("#DDDDDD"))
        painter.drawRect(8, 4, 16, 24)
        painter.drawLine(12, 12, 20, 12)
        painter.drawLine(12, 16, 20, 16)
        painter.drawLine(12, 20, 20, 20)
        painter.end()

        # 检查文件是否存在
        if not os.path.exists(file_path):
            print(f"文件不存在: {file_path}")
            return default_pixmap

        try:
            # 方法1: 使用QFileIconProvider
            provider = QFileIconProvider()
            fileInfo = QFileInfo(file_path)
            icon = provider.icon(fileInfo)
            if not icon.isNull():
                pixmap = icon.pixmap(32, 32)
                if not pixmap.isNull() and pixmap.width() > 0:
                    return pixmap
        except Exception as e:
            print(f"使用QFileIconProvider提取图标失败: {e}")

        try:
            # 方法2: 使用QIcon直接获取
            icon = QIcon(file_path)
            if not icon.isNull():
                pixmap = icon.pixmap(32, 32)
                if not pixmap.isNull() and pixmap.width() > 0:
                    return pixmap
        except Exception as e:
            print(f"使用QIcon提取图标失败: {e}")

        # 方法3: 根据扩展名创建图标
        try:
            extension = os.path.splitext(file_path)[1]
            if extension:
                return create_fallback_icon(extension, 32)
        except Exception as e:
            print(f"创建扩展名图标失败: {e}")

        # 如果所有方法都失败，返回默认图标
        return default_pixmap

    except Exception as e:
        print(f"提取图标过程中出现严重错误: {e}")
        # 最后尝试创建空白图标
        try:
            pixmap = QPixmap(32, 32)
            pixmap.fill(Qt.transparent)
            return pixmap
        except:
            return None
